package com.xhwl.centiotdata.suppliersystem.haikang;

import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.pojo.constant.HaiKangConstant;
import com.xhwl.centiotdata.pojo.constant.StrConstant;
import com.xhwl.centiotdata.utils.RedisUtils;
import com.xhwl.common.exception.ApplicationException;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author： lianghz
 * @Description：
 * @Date 2021/09/03/ 10:15
 */
@Service
public class GeneralHaiKangHandler {
    private static final Logger log = LoggerFactory.getLogger(GeneralHaiKangHandler.class);

    @Autowired
    private RedisUtils redisUtils;

    public JSONObject post(String url, Object params, Integer projectId, Integer productId, String ipAndPort, String ak, String sk, String tagId) {
        String path = new StringBuffer(ipAndPort).append(HaiKangConstant.ARTEMIS).append(url).toString();
        String result = null;
        String jsonParam = JSON.toJSONString(params);
        jsonParam = jsonParam.replace("\\r\\n", "");
        try {
            Map<String, String> header = new HashMap<>();
            header.put(HaiKangConstant.ACCESS_TOKEN, this.getAccessToken(projectId, productId, ipAndPort, ak, sk));
            if (StringUtils.isNotEmpty(tagId)) {
                header.put("tagId", tagId);
            }
            result = HttpRequest
                    .post(path)
                    .addHeaders(header)
                    .body(jsonParam)
                    .setConnectionTimeout(3000)
                    .setReadTimeout(5000)
                    .execute()
                    .body();
        } catch (HttpException e) {
            log.error("【HaiKang post exception】path:{};params:{}", path, jsonParam);
        }
        if (StringUtils.isEmpty(result)) {
            log.error("【HaiKang post result is null】path:{}", path + "  " + jsonParam);
        }
        JSONObject resultObject = JSON.parseObject(result);
        if (!"0".equals(resultObject.getString("code"))) {
            log.error("【HaiKang post failed】path:{};params:{};msg:{}", path, jsonParam, resultObject.getString("msg"));
        }
        Object data = resultObject.get("data");
        if (data instanceof JSONObject) {
            return resultObject.getJSONObject("data");
        } else {
            return resultObject;
        }
    }

    private String getAccessToken(Integer projectId, Integer productId, String ipAndPort, String ak, String sk) {
        ReentrantLock lock = new ReentrantLock();
        String accessToken = null;
        lock.lock();
        try {
            String key = new StringBuffer(StrConstant.SUPPLIER_SYSTEM_TOKEN).append("-").append(projectId).append("-").append(productId).toString();
            Object value = redisUtils.get(key);
            if (value == null) {
                accessToken = this.requestAccessToken(ipAndPort, ak, sk);
                // 设置或更新过期时间
                redisUtils.setWithMinute(key, accessToken, 10);
            } else {
                accessToken = (String) value;
            }
        } catch (Exception e) {
            log.error("【HaiKang getAccessToken exception】projectId:{}", projectId);
            e.printStackTrace();
            throw new ApplicationException();
        } finally {
            lock.unlock();
        }
        return accessToken;
    }

    private String requestAccessToken(String ipAndPort, String ak, String sk) {
        String path = new StringBuffer(ipAndPort).append(HaiKangConstant.ARTEMIS).append(HaiKangConstant.TOKEN_URL).toString();
        String result = null;
        try {
            result = HttpUtil.createPost(path)
                    .form(HaiKangConstant.CLIENT_ID, ak)
                    .form(HaiKangConstant.CLIENT_SECRET, sk)
                    .setConnectionTimeout(3000)
                    .setReadTimeout(5000)
                    .execute()
                    .body();
        } catch (HttpException e) {
            log.error("【HaiKang requestAccessToken exception】path:{};ak:{};sk:{}", path, ak, sk);
            e.printStackTrace();
            throw new ApplicationException();
        }
        if (StringUtils.isEmpty(result)) {
            log.error("【HaiKang requestAccessToken result is null】path:{};ak:{};sk:{}", path, ak, sk);
            throw new BusinessException();
        }
        JSONObject resultObject = JSON.parseObject(result);
        return resultObject.getString("access_token");
    }

}
